package com.pumpkin.esapi.controller;

import com.alibaba.fastjson.JSON;
import com.pumpkin.esapi.pojo.User;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/elastic")
public class ElasticSearchTestController {

    @Resource
    private RestHighLevelClient restHighLevelClient;

    /**
     * 测试创建索引
     * 通过request
     */
    @GetMapping("createIndex")
    public void testCreateIndex() throws IOException {
        //创建索引请求
        CreateIndexRequest request = new CreateIndexRequest("pumpkin_index");
        //客户端执行请求IndicesClient，请求后获得响应
        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(createIndexResponse);
    }

    /**
     * 测试获取索引，只能测试是否存在
     * @throws IOException
     */
    @GetMapping("getIndex")
    public void testGetIndex() throws IOException {
        //创建请求
        GetIndexRequest request = new GetIndexRequest("pumpkin_index");
        //客户端执行请求IndicesClient，请求后获得响应
        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println("是否存在：" + exists);
    }

    /**
     * 测试删除索引
     * @throws IOException
     */
    @GetMapping("deleteIndex")
    public void testDeleteIndex() throws IOException {
        //创建请求
        DeleteIndexRequest request = new DeleteIndexRequest("pumpkin_index");
        //客户端执行请求IndicesClient，请求后获得响应
        AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
        System.out.println("是否删除完成：" + acknowledgedResponse.isAcknowledged());
    }

    /**
     * 测试添加文档
     * @throws IOException
     */
    @GetMapping("createDocument")
    public void testCreateDocument() throws IOException {
        //创建对象
        User user = new User("pumpkin", 23);
        //创建请求
        IndexRequest request = new IndexRequest("pumpkin_index");
        request.id("1");
        request.timeout(TimeValue.timeValueSeconds(1));
        //将我们的数据放入请求中 json格式的数据
        IndexRequest source = request.source(JSON.toJSONString(user), XContentType.JSON);
        //客户端发送请求，获取响应结果
        IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        System.out.println(indexResponse.toString());
        System.out.println(indexResponse.status());
    }

    /**
     * 测试文档是否存在
     */
    @GetMapping("getDocument")
    public void testGetDocument() throws IOException {
        GetRequest request = new GetRequest("pumpkin_index", "1");
        //不获取返回的_source上下文
        request.fetchSourceContext(new FetchSourceContext(false));
        request.storedFields("_none_");
        boolean exists = restHighLevelClient.exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    /**
     * 测试获取文档信息
     */
    @GetMapping("getDocumentInfo")
    public void testGetDocumentInfo() throws IOException {
        GetRequest request = new GetRequest("pumpkin_index", "1");
        GetResponse getResponse = restHighLevelClient.get(request, RequestOptions.DEFAULT);

        System.out.println(getResponse.getSourceAsString());
        System.out.println(getResponse);
    }

    /**
     * 测试更新文档信息
     */
    @GetMapping("updateDocumentInfo")
    public void testUpdateDocumentInfo() throws IOException {
        UpdateRequest request = new UpdateRequest("pumpkin_index", "1");
        request.timeout("1s");
        User user = new User("南瓜", 22);

        request.doc(JSON.toJSONString(user),XContentType.JSON);

        UpdateResponse update = restHighLevelClient.update(request, RequestOptions.DEFAULT);
        System.out.println(update);
        System.out.println(update.status());

    }

    /**
     * 测试删除文档信息
     */
    @GetMapping("delDocumentInfo")
    public void testDelDocumentInfo() throws IOException {
        DeleteRequest request = new DeleteRequest("pumpkin_index", "1");
        request.timeout("1s");

        DeleteResponse delete = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
        System.out.println(delete);
        System.out.println(delete.status());

    }

    /**
     * 测试插入大批量数据
     */
    @GetMapping("saveBulk")
    public void testBatchInsert() throws IOException {
        BulkRequest request = new BulkRequest();
        request.timeout("10s");
        List<User> userList = new ArrayList<>();
        userList.add(new User("pumpkin1",20));
        userList.add(new User("pumpkin2",21));
        userList.add(new User("pumpkin3",22));
        userList.add(new User("pumpkin4",23));
        userList.add(new User("pumpkin5",24));
        userList.add(new User("pumpkin6",25));

        for (int i = 0; i < userList.size(); i++) {
            request.add(new IndexRequest("pumpkin_index").id("" + (i + 1)).source(JSON.toJSONString(userList.get(i)),XContentType.JSON));
        }

        BulkResponse bulk = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
        System.out.println(bulk);
        System.out.println(bulk.status());

    }

    /**
     * 查询操作
     * SearchRequest 搜索请求
     * SearchSourceBuilder 条件构造
     * HighlightBuilder 构建高亮
     * TermQueryBuilder 精确查询
     * MatchAllQueryBuilder 匹配所有
     * xxx QueryBuilder 对应刚才看到的所有命令
     * @throws IOException
     */
    @GetMapping("queryCondition")
    public void testQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("pumpkin_index");
        //构建搜索条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询条件可以使用QueryBuilders工具实现
        //QueryBuilders.termQuery 是精确查照
        //QueryBuilders.matchAllQuery 匹配所有
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "pumpkin1");
//        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();

        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        searchRequest.source(sourceBuilder);

        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(searchResponse.getHits()));
        System.out.println("================");
        for (SearchHit documentFields : searchResponse.getHits().getHits()) {
            System.out.println(documentFields.getSourceAsMap());
        }
    }
}
